package com.lms.service.impl;


import com.lms.bean.Role;
import com.lms.bean.Type;
import com.lms.bean.User;
import com.lms.dao.RoleDao;
import com.lms.dao.UserDao;
import com.lms.service.UserService;
import com.lms.util.MD5Util;
import com.lms.util.MyBeanUtils;
import com.lms.util.MyStringUtils;
import com.lms.util.QueryResult;
import com.lms.vo.UserVO;

import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;


import javax.persistence.OneToMany;
import javax.persistence.criteria.*;
import java.util.ArrayList;
import java.util.List;

@Service
public class UserServiceImpl implements UserService {
    @Autowired
    private UserDao userDao;
    @Autowired
    private RoleDao roleDao;

    @Override
    public Long getTotalCount() {
        return userDao.count();
    }

    @Override
    public List<UserVO> findAll(int page, int pageSize) {
        Sort sort = Sort.by(Sort.Direction.ASC, "userId");
        Pageable pageable = PageRequest.of(page, pageSize, sort);
        List<User> list = userDao.getList(pageable);
        List<UserVO> userVOList = new ArrayList<>();
        list.forEach(user -> userVOList.add(UserVO.convert(user)));
        return userVOList;
    }

    @Override
    public User findUserById(Long userId) {
        return userDao.findById(userId).orElse(null);
    }

    @Override
    public User checkUser(String username, String password){
        return userDao.findByUsernameAndPassword(username,password);
    }
    @Override
    public void save(User user) {

        if(null==user.getUserId()){
            //插入
            if(StringUtils.isEmpty(user.getPassword())){
                user.setPassword(user.getUsername());
            }
            user.setPassword(MD5Util.code(user.getPassword()));

        }else{
            //更新
            User one = userDao.getOne(user.getUserId());
            if(StringUtils.isEmpty(user.getPassword())){
                user.setPassword(null);
            }else {
                user.setPassword(MD5Util.code(user.getPassword()));
            }
            BeanUtils.copyProperties(user,one,MyBeanUtils.getNullPropertyNames(user));
            user = one;

        }
        user.setRole(roleDao.getOne(user.getRole().getRoleId()));
        userDao.save(user);
    }

    @Override
    public void deleteById(Long userId) {
        try {
            userDao.deleteById(userId);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public void deleteAll(String ids) {
        //要事先判断这个UserId是不是其他表的外键，如果是，则不能删除  这个地方肯定会引起 Bug
        List<Long> Ids = new ArrayList<>();
        String[] split = ids.split(",");
        for (String s : split) {
            if (MyStringUtils.isNumeric(s)) {
                Ids.add(Long.parseLong(s));
            }
        }
        for (Long id : Ids) {
            deleteById(id);
        }
    }

    @Override
    public QueryResult<UserVO> queryByKeyWordLikeNoType(int page, int pageSize, User param) {
        Specification<User> specification = new Specification<User>() {
            @Override
            public Predicate toPredicate(Root<User> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
                List<Predicate> predicates = new ArrayList<>();
                setQueryParam(root, criteriaBuilder, predicates, param);
                Predicate[] ts = new Predicate[predicates.size()];
                criteriaQuery.where(predicates.toArray(ts));
                return null;
            }
        };
        return getUserVOQueryResult(page, pageSize, specification);
    }

    @Override
    public QueryResult<UserVO> queryByKeyWordLikeWithType(int page, int pageSize, User param, long roleId) {

        Specification<User> specification = new Specification<User>() {
            @Override
            public Predicate toPredicate(Root<User> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
                List<Predicate> predicates = new ArrayList<>();
                setQueryParam(root, criteriaBuilder, predicates, param);
                predicates.add(criteriaBuilder.equal(root.<Role>get("role").get("roleId"), roleId));
                Predicate[] ts = new Predicate[predicates.size()];
                criteriaQuery.where(predicates.toArray(ts));
                return null;
            }
        };
        return getUserVOQueryResult(page, pageSize, specification);
    }

    @Override
    public void changeUserInfo(User user) {
        User one = userDao.getOne(user.getUserId());
        String password = user.getPassword();
        user.setPassword(MD5Util.code(password));
        BeanUtils.copyProperties(user,one, MyBeanUtils.getNullPropertyNames(user));
        userDao.save(one);
    }

    private QueryResult<UserVO> getUserVOQueryResult(int page, int pageSize, Specification<User> specification) {
        Sort sort = Sort.by(Sort.Direction.ASC, "userId");
        Pageable pageable = PageRequest.of(page, pageSize, sort);
        Page<User> userPage = userDao.findAll(specification, pageable);

        List<User> list = userPage.getContent();
        List<UserVO> userVOList = new ArrayList<>();
        list.forEach(user-> userVOList.add(UserVO.convert(user)));

        QueryResult<UserVO> queryResult = new QueryResult<>();
        queryResult.setTotalCount(userPage.getTotalElements());
        queryResult.setData(userVOList);
        return queryResult;
    }

    private void setQueryParam(Root<User> root, CriteriaBuilder criteriaBuilder, List<Predicate> predicates, User param) {
        String username = param.getUsername();
        Predicate q1 = criteriaBuilder.like(root.<String>get("username"), "%" + username + "%");
        predicates.add(criteriaBuilder.or(q1));
    }
}